package com.wispx.gateway.core.filter.gray.strategy;

import com.wispx.gateway.config.pojo.RouteDefinition;
import com.wispx.gateway.config.pojo.ServiceInstance;
import com.wispx.gateway.config.util.FilterConfigUtil;
import com.wispx.gateway.core.context.GatewayContext;

import java.util.List;
import java.util.Optional;
import java.util.Set;

import static com.wispx.gateway.common.constant.FilterConstant.GRAY_FILTER_NAME;
import static com.wispx.gateway.common.constant.GrayConstant.MAX_GRAY_RATIO;
import static com.wispx.gateway.common.constant.GrayConstant.RATIO_GRAY_STRATEGY;

/**
 * 根据流量判断是否走灰度
 */
public class ThresholdGrayStrategy implements GrayStrategy {
    @Override
    public boolean shouldRoute2Gray(GatewayContext context, List<ServiceInstance> instances) {
        if (instances.stream().anyMatch(instance -> instance.isEnable() && !instance.isGray())) {
            // 存在非灰度实例
            Set<RouteDefinition.FilterConfig> filters = context.getRouteDefinition().getFilterConfigs();
            RouteDefinition.GaryFilterConfig garyFilterConfig = FilterConfigUtil.findFilterConfigByClass(filters, GRAY_FILTER_NAME, RouteDefinition.GaryFilterConfig.class);
            double maxGrayRatio = instances.stream().mapToDouble(ServiceInstance::getGrayRatio).sum();
            maxGrayRatio = Math.min(maxGrayRatio, Optional.ofNullable(garyFilterConfig.getMaxGrayRadio()).orElse(MAX_GRAY_RATIO));
            return Math.random() <= maxGrayRatio;
        }
        // 都是灰度实例
        return true;
    }

    @Override
    public String mark() {
        return RATIO_GRAY_STRATEGY;
    }
}
